/**
 * $version:  0.1 
 * $Date: 2011-01-21 
 *
 * Copyright (C) 2010-2011 Jawa Software. All rights reserved.
 *
 */

package org.jawa.user;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.jawa.core.cache.Cache;
import org.jawa.core.cache.CacheFactory;
import org.jawa.core.exception.UserNotFoundException;
import org.jawa.core.util.ClassUtils;
import org.jawa.core.util.JawaGlobals;
import org.jawa.user.event.UserEventDispatcher;
import org.jawa.user.event.UserEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 用户管理，包括加载、查询、创建、删除以及修改.
 * 
 * @see User
 */
public class UserManager {

	private static final Logger Log = LoggerFactory.getLogger(UserManager.class);

	// 单一实例.
	private static class UserManagerContainer {
		private static UserManager instance = new UserManager();
	}

	/**
	 * 返回当前用户操作提供类.
	 * 
	 * @return 用户操作提供类.
	 */
	public static UserProvider getUserProvider() {
		return UserManagerContainer.instance.provider;
	}

	/**
	 * 返回 UserManager 的单一实例.
	 * 
	 * @return UserManager 实例.
	 */
	public static UserManager getInstance() {
		return UserManagerContainer.instance;
	}

	/** 当前用户的缓存. */
	private Cache<Long, User> userCache;

	private UserProvider provider;

	private UserManager() {
		// 初始化缓存.
		userCache = CacheFactory.createCache("User");

		// 初始化用户操作提供类.
		initProvider();

		// 注册事件.
		UserEventListener userListener = new UserEventListener() {
			public void userCreated(User user, Map<String, Object> params) {
				userCache.put(user.getUserId(), user);
			}

			public void userDeleting(User user, Map<String, Object> params) {
				userCache.remove(user.getUserId());
			}

			public void userModified(User user, Map<String, Object> params) {
				userCache.put(user.getUserId(), user);
			}
		};
		UserEventDispatcher.addListener(userListener);
	}

	/**
	 * 创建用户.
	 * 
	 * @param user
	 *            要创建的用户.
	 * @return a new User.
	 * @throws Exception 
	 *             用户操作提供类不支持的方法
	 */
	public User createUser(User user) throws Exception {

		if (null == user) {
			throw new NullPointerException("用户不可以为空！");
		}

		if (null == user.getUserId()) {
			throw new IllegalArgumentException("用户  userId 不可以为空！");
		}

		if (null == user.getUserName()) {
			throw new IllegalArgumentException("用户  UserName 不可以为空！");
		}

		if (StringUtils.isEmpty(user.getLoginNo())) {
			throw new IllegalArgumentException("用户  LoginNo 不可以为空！");
		}

		user = provider.createUser(user);
		userCache.put(user.getUserId(), user);

		// 激活事件.
		Map<String, Object> params = Collections.emptyMap();
		UserEventDispatcher.dispatchEvent(user, UserEventDispatcher.EventType.user_created, params);
		return user;
	}

	/**
	 *  更新用户的部份信息.
	 * @param userId
	 * @param brId
	 * @param loginNo
	 * @param userName
	 * @param userType
	 * @param userStatus
	 * @param userSex
	 * @param userPhone
	 * @param userEmail
	 * @param userPicture
	 * @return
	 * @throws Exception
	 */
	public User updateUser(Long userId, String brId, String loginNo, String userName, String userType,
			String userStatus, String userSex, String userPhone, String userEmail, String userPicture) throws Exception {

		if (null == userId) {
			throw new IllegalArgumentException("用户  userId 不可以为空！");
		}

		if (null == userName) {
			throw new IllegalArgumentException("用户  UserName 不可以为空！");
		}

		if (StringUtils.isEmpty(loginNo)) {
			throw new IllegalArgumentException("用户  LoginNo 不可以为空！");
		}

		User user = getUser(userId);
		user.setBrId(Long.valueOf(brId));
		user.setLoginNo(loginNo);
		user.setUserName(userName);
		user.setUserType(userType);
		user.setUserStatus(userStatus);
		user.setUserSex(userSex);
		user.setUserPhone(userPhone);
		user.setUserEmail(userEmail);
		user.setUserPicture(userPicture);
		
		//更新用户
		//provider.updateUser(user);
		userCache.put(user.getUserId(), user);

		// 激活事件.
		Map<String, Object> params = Collections.emptyMap();
		UserEventDispatcher.dispatchEvent(user, UserEventDispatcher.EventType.user_modified, params);
		return user;
	}

	/**
	 * 删除用户.
	 * 
	 * @param user
	 *            要删除的用户.
	 */
	public void deleteUser(Long userId) {
		User user = null;
		try {
			user = getUser(userId);
		} catch (UserNotFoundException e) {
			//忽略
		}
		// 激活事件.
		Map<String, Object> params = Collections.emptyMap();
		UserEventDispatcher.dispatchEvent(user, UserEventDispatcher.EventType.user_deleting, params);

		provider.deleteUser(user.getUserId());
		userCache.remove(user.getUserId());
	}

	/**
	 * 返回指定 username 的用户.
	 * 
	 * @param username
	 *            用户的 username.
	 * @return username 等于 <tt>username</tt> 的用户.
	 * @throws UserNotFoundException
	 *             用户没有找到.
	 */
	public User getUserByUsername(String username) throws UserNotFoundException {
		if (username == null) {
			throw new UserNotFoundException("Username 不可以为空!");
		}
		User user = provider.loadUserByUsername(username);
		userCache.put(user.getUserId(), user);
		return user;
	}

	/**
	 * 返回指定 userId 的用户.
	 * 
	 * @param userId
	 *            用户的 userId .
	 * @return userId 等于 <tt>userId</tt> 的用户.
	 * @throws UserNotFoundException
	 *             用户没有找到.
	 */
	public User getUser(Long userId) throws UserNotFoundException {
		if (userId == null) {
			throw new UserNotFoundException("UserId cannot be null");
		}

		User user = userCache.get(userId);
		if (user == null) {
			synchronized (userId) {
				user = userCache.get(userId);
				if (user == null) {
					user = provider.loadUserByUserid(userId);
					userCache.put(user.getUserId(), user);
				}
			}
		}
		return user;
	}

	/**
	 * 返回系统中的总用户数.
	 * 
	 * @return 系统中的总用户数.
	 */
	public int getUserCount() {
		return provider.getUserCount();
	}

	/**
	 * 返回系统中所有的用户，不可以修改的.
	 * 
	 * @return 不可以修改的用户集合.
	 */
	public Collection<User> getUsers() {
		return provider.getUsers();
	}

	/**
	 * 返回系统中所有的用户的 userId 集合，不可以修改的.
	 * 
	 * @return 不可以修改的用户userId 的集合.
	 */
	public Collection<Long> getUserIds() {
		return provider.getUserIds();
	}

	/**
	 * 返回索引范围内的用户集合。
	 * 
	 * @param startIndex
	 *            起始索引.
	 * @param numResults
	 *            要显示的用户数据数量.
	 * @return 用户集合.
	 */
	public Collection<User> getUsers(int startIndex, int numResults) {
		return provider.getUsers(startIndex, numResults);
	}

	/**
	 * 根据查询条件，返回用户集合。
	 * 
	 * @param fields
	 *            查询字段.
	 * @param query
	 *            查询字段条件值.
	 * @return 用户集合.
	 */
	public Collection<User> findUsers(List<String> fields, List<String> query) {
		return provider.findUsers(fields, query);
	}

	/**
	 * 根据查询条件，返回索引范围内的用户集合。
	 * 
	 * @param fields
	 *            查询字段.
	 * @param query
	 *            查询字段条件值.
	 * @param startIndex
	 *            起始索引.
	 * @param numResults
	 *            要显示的用户数据数量.
	 * @return 用户集合.
	 */
	public Collection<User> findUsers(List<String> fields, List<String> query, int startIndex, int numResults) {
		return provider.findUsers(fields, query, startIndex, numResults);
	}

	private void initProvider() {
		JawaGlobals.getProperty("provider.user.className");

		String className = JawaGlobals.getProperty("provider.user.className", "org.jawa.user.DefaultUserProvider");
		if (provider == null || !className.equals(provider.getClass().getName())) {
			try {
				Class c = ClassUtils.forName(className);
				provider = (UserProvider) c.newInstance();
			} catch (Exception e) {
				Log.error("不能加载用户操作的提供类: " + className, e);
				provider = new DefaultUserProvider();
			}
		}
	}

	/**
	 * 是否是系统中注册过的用户.
	 * @param username 用户登录名
	 * @return
	 */
	public boolean isRegisteredUser(String username) {
		if (username == null || "".equals(username)) {
			return false;
		}
		try {
			getUserByUsername(username);
			return true;
		} catch (UserNotFoundException e) {
			return false;
		}
	}
}